package com.liwenfeng;

import com.liwenfeng.domain.Account;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class SerializableTest {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //可序列化的函数对象
        Type1 lambda = (Type1 & Serializable) Account::getName;
//        Type1 lambda = (Type1 & Serializable) acccount->acccount.getName();
        for (Method method : lambda.getClass().getDeclaredMethods()) {
            System.out.println(method);
        }
//        private final java.lang.Object com.liwenfeng.SerializableTest$$Lambda/0x0000019f64004000.writeReplace()
        System.out.println("-------------");
        //函数对象 <==> 字节码 会额外存储类和方法的信息，
        //运行时就可以根据这些信息找到属性，从而进一步确定【列名】
        SerializedLambda invoke = (SerializedLambda) lambda.getClass().getDeclaredMethod("writeReplace").invoke(lambda);
        //invoke是新对象，包含了原始函数对象的字节码，还包含了类和方法的额外信息
        System.out.println(invoke.getClass());

        System.out.println(invoke.getCapturingClass());//哪个类使用了这个函数对象
        System.out.println(invoke.getImplClass());     //哪个类实现了函数对象的逻辑
        System.out.println(invoke.getImplMethodName());//哪个方法实现了函数对象的逻辑
/*
        方法引用得到的结果：
        com/liwenfeng/SerializableTest
        com/liwenfeng/domain/Account
        getName

        lambda表达式得到的结果：（结果没什么用，想拿到方法名只能用方法引用）
        com/liwenfeng/SerializableTest
        com/liwenfeng/SerializableTest
        lambda$main$4f21bb4a$1
*/
    }

    interface Type1{
        String abc(Account account);
    }
}
